<script setup>
import { Loading } from '@element-plus/icons-vue'
import { ref } from 'vue'
import { useInference } from '@/composables/useInference'

const props = defineProps({
  currentLi: String,
  openDialog: Function,
  uploadLoading: Boolean,
  startLoading: Boolean,
  evolutionLoading: Boolean,
  assessmentLoading: Boolean,
  issuedLoading: Boolean,
  changeLoading: Function
})

const emit = defineEmits(['update:currentLi'])

const { runUpdateSamples, runCouldEvolution, runCollaborateEvolution } = useInference()

// 添加后台执行状态
const batchExecuting = ref(false)

// Dialog显示控制
const timeSettingDialogVisible = ref(false)

// 时间设置表单
const timeSettingsForm = ref({
  upload: 5,
  start: 10,
  evolution: 15,
  assessment: 8,
  issued: 6
})

// 更新currentLi，使对应按钮显示点击效果
const updateCurrentLi = (step) => {
  // 通过父组件传递的方法更新当前选中项
  if (typeof props.openDialog === 'function') {
    // 只更新状态，不实际打开对话框
    emit('update:currentLi', step)
  }
}

// 开始执行所有步骤
const startExecution = async () => {
  timeSettingDialogVisible.value = false
  batchExecuting.value = true

  // 计算每个步骤的开始时间（相对于执行开始的时间，单位：毫秒）
  const startTime = Date.now()
  const stepStartTimes = {
    upload: 0,
    start: timeSettingsForm.value.upload * 1000,
    evolution: (timeSettingsForm.value.upload + timeSettingsForm.value.start) * 1000,
    assessment:
      (timeSettingsForm.value.upload +
        timeSettingsForm.value.start +
        timeSettingsForm.value.evolution) *
      1000,
    issued:
      (timeSettingsForm.value.upload +
        timeSettingsForm.value.start +
        timeSettingsForm.value.evolution +
        timeSettingsForm.value.assessment) *
      1000,
    end:
      (timeSettingsForm.value.upload +
        timeSettingsForm.value.start +
        timeSettingsForm.value.evolution +
        timeSettingsForm.value.assessment +
        timeSettingsForm.value.issued) *
      1000
  }

  // 确保在预定时间执行步骤的辅助函数
  const executeAtScheduledTime = async (stepName, timeOffset, executeFn) => {
    const now = Date.now()
    const elapsedTime = now - startTime
    const remainingTime = timeOffset - elapsedTime

    // 如果还没到执行时间，等待到执行时间
    if (remainingTime > 0) {
      await new Promise((resolve) => setTimeout(resolve, remainingTime))
    }

    // 执行步骤
    try {
      await executeFn()
    } catch (error) {
      console.error(`执行${stepName}步骤失败:`, error)
    }
  }

  try {
    // 1. 执行边侧难辨样本上传
    await executeAtScheduledTime('upload', stepStartTimes.upload, async () => {
      updateCurrentLi('upload')
      props.changeLoading('upload', true)
      await runUpdateSamples({
        edgeID: [0],
        threshold: '0.5',
        SCloud: true,
        ZCloud: true
      })
    })

    // 2. 执行云侧模型增量学习
    await executeAtScheduledTime('start', stepStartTimes.start, async () => {
      props.changeLoading('upload', false)
      updateCurrentLi('start')
      props.changeLoading('start', true)
      await runCouldEvolution({
        model: 'Vit',
        task: 'qjxs',
        method: 'Quest',
        lr: 0.001,
        epoch: 10,
        batchSize: 32,
        dataStartTime: new Date(new Date().setDate(new Date().getDate() - 7)),
        dataEndTime: new Date()
      })
    })

    // 3. 执行云边模型协同进化
    await executeAtScheduledTime('evolution', stepStartTimes.evolution, async () => {
      props.changeLoading('start', false)
      updateCurrentLi('evolution')
      props.changeLoading('evolution', true)
      await runCollaborateEvolution({
        Smodel: 'Vit',
        Zmodel: 'Vit',
        task: 'qjxs',
        method: 'Quest',
        lr: 0.001,
        epoch: 10,
        batchSize: 32,
        dataStartTime: new Date(new Date().setDate(new Date().getDate() - 7)),
        dataEndTime: new Date()
      })
    })

    // 4. 执行云边进化模型评估
    await executeAtScheduledTime('assessment', stepStartTimes.assessment, async () => {
      props.changeLoading('evolution', false)
      updateCurrentLi('assessment')
      props.changeLoading('assessment', true)
    })

    // 5. 执行进化模型下发边侧
    await executeAtScheduledTime('issued', stepStartTimes.issued, async () => {
      props.changeLoading('assessment', false)
      updateCurrentLi('issued')
      props.changeLoading('issued', true)
    })

    // 完成所有步骤
    await executeAtScheduledTime('end', stepStartTimes.end, async () => {
      props.changeLoading('issued', false)
      // 清除选中状态
      updateCurrentLi('')
    })
  } catch (error) {
    console.error('批量执行过程中发生错误:', error)
  } finally {
    // 确保最终状态正确
    setTimeout(() => {
      // 确保所有loading状态都关闭
      props.changeLoading('upload', false)
      props.changeLoading('start', false)
      props.changeLoading('evolution', false)
      props.changeLoading('assessment', false)
      props.changeLoading('issued', false)
      updateCurrentLi('')
      batchExecuting.value = false
    }, stepStartTimes.end + 10)
  }
}

// 修改后的后台执行方法 - 现在只是显示设置对话框
const batchExecute = () => {
  if (batchExecuting.value) return

  // 显示时间设置对话框
  timeSettingDialogVisible.value = true
}

// 取消操作
const cancelExecution = () => {
  timeSettingDialogVisible.value = false
}

// 暴露方法给父组件
defineExpose({
  batchExecute
})
</script>

<template>
  <div class="top5">
    <div class="top5-title">
      <span>云边分布式协同进化</span>
      <el-button class="exec-btn" size="small" @click="batchExecute" :loading="batchExecuting"
        >后台执行</el-button
      >
    </div>
    <div class="top5-content">
      <ul>
        <li @click="openDialog('upload')">
          <div :class="props.currentLi === 'upload' ? 'cicle-selected' : 'cicle'"></div>
          <div :class="props.currentLi === 'upload' ? 'li-content-selected' : 'li-content'">
            <span>边侧难辨样本上传</span>

            <span v-if="uploadLoading" class="loading-icon">
              <el-icon><Loading /></el-icon>
            </span>
          </div>
        </li>
        <li @click="openDialog('start')">
          <div :class="props.currentLi === 'start' ? 'cicle-selected' : 'cicle'"></div>
          <div :class="props.currentLi === 'start' ? 'li-content-selected' : 'li-content'">
            <span>云侧模型增量学习</span>

            <span v-if="startLoading" class="loading-icon">
              <el-icon><Loading /></el-icon>
            </span>
          </div>
        </li>
        <li @click="openDialog('evolution')">
          <div :class="props.currentLi === 'evolution' ? 'cicle-selected' : 'cicle'"></div>
          <div :class="props.currentLi === 'evolution' ? 'li-content-selected' : 'li-content'">
            <span>云边模型协同进化</span>

            <span v-if="evolutionLoading" class="loading-icon">
              <el-icon><Loading /></el-icon>
            </span>
          </div>
        </li>
        <li @click="openDialog('assessment')">
          <div :class="props.currentLi === 'assessment' ? 'cicle-selected' : 'cicle'"></div>
          <div :class="props.currentLi === 'assessment' ? 'li-content-selected' : 'li-content'">
            <span>云边进化模型评估</span>

            <span v-if="assessmentLoading" class="loading-icon">
              <el-icon><Loading /></el-icon>
            </span>
          </div>
        </li>
        <li @click="openDialog('issued')">
          <div :class="props.currentLi === 'issued' ? 'cicle-selected' : 'cicle'"></div>
          <div :class="props.currentLi === 'issued' ? 'li-content-selected' : 'li-content'">
            <span>进化模型下发边侧</span>
            <span v-if="issuedLoading" class="loading-icon">
              <el-icon><Loading /></el-icon>
            </span>
          </div>
        </li>
      </ul>
    </div>

    <!-- 时间设置对话框 -->
    <el-dialog
      v-model="timeSettingDialogVisible"
      title="设置执行时间"
      width="350px"
      :close-on-click-modal="false"
      :show-close="false"
      class="time-setting-dialog"
    >
      <el-form :model="timeSettingsForm" label-position="left" label-width="180px">
        <el-form-item label="边侧难辨样本上传(秒)：">
          <el-input-number v-model="timeSettingsForm.upload" :min="1" :max="60" size="small" />
        </el-form-item>
        <el-form-item label="云侧模型增量学习(秒)：">
          <el-input-number v-model="timeSettingsForm.start" :min="1" :max="60" size="small" />
        </el-form-item>
        <el-form-item label="云边模型协同进化(秒)：">
          <el-input-number v-model="timeSettingsForm.evolution" :min="1" :max="60" size="small" />
        </el-form-item>
        <el-form-item label="云边进化模型评估(秒)：">
          <el-input-number v-model="timeSettingsForm.assessment" :min="1" :max="60" size="small" />
        </el-form-item>
        <el-form-item label="进化模型下发边侧(秒)：">
          <el-input-number v-model="timeSettingsForm.issued" :min="1" :max="60" size="small" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelExecution">取消</el-button>
          <el-button type="primary" @click="startExecution">开始执行</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.top5 {
  width: 17.5%;
  height: 70%;
  float: left;

  .top5-title {
    width: 100%;
    height: 10%;
    background: url(../images/title.png) no-repeat center;
    background-size: 100%;
    color: #fff;
    position: relative;

    span {
      position: absolute;
      left: 20%;
      width: 60%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1rem;
      font-weight: 500;
      letter-spacing: var(--letter-spacing-base);
      white-space: nowrap;
    }

    .exec-btn {
      position: absolute;
      z-index: 100;
      left: 110%;
      top: 50%;
      transform: translateY(-50%);
      font-size: 0.75rem;
      padding: 2px 6px;
      height: auto;
      line-height: 1.2;
      background: linear-gradient(135deg, #09c4ca 0%, #3eacb4 100%);
      border-color: rgba(9, 196, 202, 0.5);
      color: #fff;
      box-shadow: 0 0 10px rgba(9, 196, 202, 0.3);

      &:hover,
      &:focus {
        background: linear-gradient(135deg, #3eacb4 0%, #09c4ca 100%);
        border-color: rgba(9, 196, 202, 0.8);
        box-shadow: 0 0 15px rgba(9, 196, 202, 0.5);
      }

      &:active {
        background: linear-gradient(135deg, #09c4ca 0%, #3eacb4 100%);
        border-color: rgba(9, 196, 202, 0.9);
      }
    }
  }

  .top5-content {
    width: 100%;
    height: 80%;

    ul {
      width: 100%;
      height: 100%;

      li {
        width: 100%;
        height: 15%;
        margin-top: 5%;
        position: relative;

        .li-content {
          width: 90%;
          height: 100%;
          margin-left: 5%;
          background: url(../images/border.png) no-repeat center;
          background-size: contain;
          font-size: 0.9rem;
          padding-top: 6%;
          padding-left: 15%;
          color: #fff;
          box-sizing: border-box;
          cursor: pointer;
          font-weight: 400;
          letter-spacing: var(--letter-spacing-base);

          span {
            margin-right: 2%;
          }
        }

        .cicle {
          content: '';
          display: block;
          position: absolute;
          width: 1.7rem;
          height: 1.7rem;
          background: url(../images/green.png) no-repeat center;
          background-size: 100%;
          left: 0;
          bottom: 0;
        }

        .cicle-selected {
          content: '';
          display: block;
          position: absolute;
          width: 1.7rem;
          height: 1.7rem;
          background: url(../images/orange.png) no-repeat center;
          background-size: 100%;
          left: 0;
          bottom: 0;
        }

        .li-content-selected {
          width: 90%;
          height: 100%;
          margin-left: 5%;
          background: url(../images/border2.png) no-repeat center;
          background-size: contain;
          font-size: 0.9rem;
          padding-top: 6%;
          padding-left: 15%;
          color: #fff;
          box-sizing: border-box;
          cursor: pointer;
          font-weight: 400;
          letter-spacing: var(--letter-spacing-base);

          span {
            margin-right: 2%;
          }
        }
      }
    }
  }

  // 添加发光动画效果
  @keyframes glowPulse {
    0% {
      box-shadow:
        0 0 5px #f29701,
        0 0 10px #f29701,
        0 0 15px #f29701;
      opacity: 0.8;
    }
    50% {
      box-shadow:
        0 0 10px #f29701,
        0 0 20px #f29701,
        0 0 30px #f29701;
      opacity: 1;
    }
    100% {
      box-shadow:
        0 0 5px #f29701,
        0 0 10px #f29701,
        0 0 15px #f29701;
      opacity: 0.8;
    }
  }

  @keyframes spin {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
  }

  // 修改 Loading 图标的样式
  .loading-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: rgba(242, 151, 1, 0.2);
    animation: glowPulse 1.5s ease-in-out infinite;
    margin-left: 8px;

    :deep(.el-icon) {
      font-size: 16px;
      color: #f29701;
      animation: spin 1s linear infinite;
    }
  }
}

:deep(.time-setting-dialog) {
  .el-dialog__header {
    background: linear-gradient(135deg, rgba(9, 196, 202, 0.8) 0%, rgba(62, 172, 180, 0.8) 100%);
    padding: 15px 20px;
    margin-right: 0;
    color: #fff;
    border-bottom: 1px solid rgba(9, 196, 202, 0.5);
  }

  .el-dialog__body {
    padding: 20px;
  }

  .el-form-item {
    margin-bottom: 12px;
  }

  .el-dialog__footer {
    border-top: 1px solid rgba(9, 196, 202, 0.2);
    padding: 10px 20px;
  }

  .el-button--primary {
    background: linear-gradient(135deg, #09c4ca 0%, #3eacb4 100%);
    border-color: rgba(9, 196, 202, 0.5);

    &:hover {
      background: linear-gradient(135deg, #3eacb4 0%, #09c4ca 100%);
      border-color: rgba(9, 196, 202, 0.8);
    }
  }
}
</style>
